package com.fc.push.mqtt.pool;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import com.fc.push.exception.MServerException;
import com.fc.push.mqtt.MqttConfig;

public class MqttClientFactory implements PooledObjectFactory<MqttClient>{
	
	private String serverURI;
	private MqttConnectOptions options;
	
	private static final AtomicInteger CLIENT_ID = new AtomicInteger(0);
	
	public MqttClientFactory(String serverURI,MqttConnectOptions options) {
		this.serverURI = serverURI;
		this.options = options;
	}
	
	@Override
	public PooledObject<MqttClient> makeObject() throws Exception {
		MqttClient client = null;
		try {
			client = new MqttClient(serverURI, "Client_" + CLIENT_ID.getAndIncrement(), new MemoryPersistence());
			if(options == null){
				options = new MqttConnectOptions();
				options.setCleanSession(true);
				options.setConnectionTimeout(10);
				options.setKeepAliveInterval(20);
				if(MqttConfig.getUsername() != null && !MqttConfig.getUsername().isEmpty()){
					options.setUserName(MqttConfig.getUsername());
					options.setPassword(MqttConfig.getPassword().toCharArray());
				}
			}
			client.connect(options);
		} catch (MqttException e) {
			throw new MServerException(e,"Could not make obj");
		}
		return new DefaultPooledObject<MqttClient>(client);
	}

	@Override
	public void destroyObject(PooledObject<MqttClient> p) throws Exception {
		MqttClient client = p.getObject();
		try{
			client.disconnect();
			client.close();
			
		}catch(Exception e){
			throw new MServerException(e,"Could not destroy obj");
		}
	}

	@Override
	public boolean validateObject(PooledObject<MqttClient> p) {
		MqttClient client = p.getObject();
		return client.isConnected() && client.getServerURI().equals(serverURI);
	}

	@Override
	public void activateObject(PooledObject<MqttClient> p) throws Exception {
		MqttClient client = p.getObject();
		if(!client.isConnected()){
			try{
				client.connect(options);
			}catch(Exception e){
				throw new MServerException(e,"Could not activate obj");
			}
		}
	}

	@Override
	public void passivateObject(PooledObject<MqttClient> p) throws Exception {
	}
	
}
